package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"stock-analyzer/internal/database"
	"stock-analyzer/internal/model"
	"stock-analyzer/internal/service"
	"strconv"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
)

var (
	db        *database.DB
	filterSvc *service.FilterService
	dbPath    = "stocks.db"
)

func main() {

	flag.StringVar(&dbPath, "db", "stocks.db", "SQLite数据库文件路径")
	flag.Parse()

	log.Printf("dbpath %s", dbPath)
	// 初始化数据库
	var err error
	db, err = database.NewDB(dbPath)
	if err != nil {
		log.Fatalf("Failed to initialize database: %v", err)
	}
	defer db.Close()

	// 创建筛选服务
	filterSvc = service.NewFilterService(db)

	// 设置Gin路由
	router := gin.Default()
	router.LoadHTMLGlob("web/templates/*")

	// 静态文件服务
	router.Static("/static", "./web/static")

	// 路由设置
	router.GET("/", indexHandler)
	router.GET("/api/stocks", apiStocksHandler)
	router.POST("/api/filter", apiFilterHandler)
	router.GET("/api/stock/:code", apiStockDataHandler)

	// 启动服务器
	fmt.Println("股票分析工具Web服务启动在 http://localhost:8080")
	if err := router.Run(":8080"); err != nil {
		log.Fatalf("Failed to start server: %v", err)
	}
}

func indexHandler(c *gin.Context) {
	c.HTML(http.StatusOK, "index.html", gin.H{
		"title": "股票分析工具",
	})
}

func apiStocksHandler(c *gin.Context) {
	stockCodes, err := db.GetAllStockCodes()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"stocks": stockCodes})
}

func apiFilterHandler(c *gin.Context) {
	var request struct {
		StartDate   string   `json:"start_date"`
		EndDate     string   `json:"end_date"`
		MaxDrawdown *float64 `json:"max_drawdown"`
		Windows     string   `json:"windows"`
	}

	if err := c.BindJSON(&request); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求参数"})
		return
	}

	// 解析日期
	startDate, err := time.Parse("2006-01-02", request.StartDate)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的开始日期格式"})
		return
	}

	endDate, err := time.Parse("2006-01-02", request.EndDate)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的结束日期格式"})
		return
	}

	log.Printf("%s -> %s ,windows:%v", startDate.Format("20060102"), endDate.Format("20060102"), request.Windows)
	// 解析窗口规则
	windowChanges, err := parseWindowRules(request.Windows)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 创建筛选条件
	condition := model.FilterCondition{
		StartDate:     startDate,
		EndDate:       endDate,
		MaxDrawdown:   request.MaxDrawdown,
		WindowChanges: windowChanges,
	}

	// 执行筛选
	results, err := filterSvc.FilterStocks(condition)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"condition": condition,
		"results":   results,
		"count":     len(results),
	})
}

func apiStockDataHandler(c *gin.Context) {
	stockCode := c.Param("code")
	startDateStr := c.DefaultQuery("start_date", time.Now().AddDate(0, 0, -60).Format("2006-01-02"))
	endDateStr := c.DefaultQuery("end_date", time.Now().Format("2006-01-02"))

	startDate, err := time.Parse("2006-01-02", startDateStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的开始日期参数"})
		return
	}

	endDate, err := time.Parse("2006-01-02", endDateStr)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的结束日期参数"})
		return
	}

	data, err := filterSvc.GetStockData(stockCode, startDate, endDate)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"stock_code": stockCode,
		"data":       data,
		"count":      len(data),
	})
}

func parseWindowRules(rulesStr string) ([]model.WindowChangeRule, error) {
	if rulesStr == "" {
		return nil, nil
	}

	var rules []model.WindowChangeRule
	ruleParts := strings.Split(rulesStr, ",")

	for _, part := range ruleParts {
		fields := strings.Split(part, ":")
		if len(fields) != 3 {
			return nil, fmt.Errorf("无效的窗口规则格式: %s", part)
		}

		window, err := strconv.Atoi(fields[0])
		if err != nil {
			return nil, fmt.Errorf("无效的窗口大小: %s", fields[0])
		}

		change, err := strconv.ParseFloat(fields[1], 64)
		if err != nil {
			return nil, fmt.Errorf("无效的涨跌幅值: %s", fields[1])
		}

		ruleType := fields[2]
		if !isValidRuleType(ruleType) {
			return nil, fmt.Errorf("无效的条件类型: %s (必须是 gt, lt, ge, le)", ruleType)
		}

		rules = append(rules, model.WindowChangeRule{
			Window: window,
			Change: change,
			Type:   ruleType,
		})
	}

	return rules, nil
}

func isValidRuleType(ruleType string) bool {
	switch ruleType {
	case "gt", "lt", "ge", "le":
		return true
	default:
		return false
	}
}

// 辅助函数：将结果转换为前端友好的格式
func convertToFrontendFormat(results []model.StockResult) []map[string]interface{} {
	var formatted []map[string]interface{}
	for _, result := range results {
		item := map[string]interface{}{
			"stock_code":   result.StockCode,
			"max_drawdown": result.MaxDrawdown,
			"passed":       result.Passed,
		}

		windowChanges := make(map[int]float64)
		for _, wc := range result.WindowChanges {
			windowChanges[wc.Window] = wc.Change
		}
		item["window_changes"] = windowChanges

		formatted = append(formatted, item)
	}
	return formatted
}
